﻿using MiniFox.Infrastructure.Attributes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MiniFox.Infrastructure
{
    /// <summary>
    /// 树组
    /// </summary>
    /// <typeparam name="D">自联结构扁平数据对象</typeparam>
    /// <typeparam name="T">节点数据对象类型</typeparam>
    public class TreeGroup<D, T> : TreeGroup<D>
    {
        Func<D, T> _mappingFunc;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="groupId"></param>
        /// <param name="groupFlatData"></param>
        /// <param name="mappingNodeData"></param>
        public TreeGroup(object groupId, IEnumerable<D> groupFlatData, Func<D, T> mappingNodeData) : base(groupId, groupFlatData)
        {
            if (mappingNodeData == null)
                throw new ArgumentNullException("mappingNodeData");
            _mappingFunc = mappingNodeData;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="groupId"></param>
        /// <param name="uniqueKey"></param>
        /// <param name="superKey"></param>
        /// <param name="sortKey"></param>
        /// <param name="groupFlatData"></param>
        /// <param name="mappingNodeData"></param>
        public TreeGroup(object groupId, string uniqueKey, string superKey, string sortKey, IEnumerable<D> groupFlatData, Func<D, T> mappingNodeData)
            : base(groupId, uniqueKey, superKey, sortKey, groupFlatData)
        {
            if (mappingNodeData == null)
                throw new ArgumentNullException("mappingNodeData");
            _mappingFunc = mappingNodeData;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        protected override ITreeNode CreateTreeNode(D flatDataItem, int level)
        {
            if (flatDataItem == null)
                return null;
            var nodeData = _mappingFunc(flatDataItem);
            if (nodeData == null)
                return null;
            var treeNode = new TreeNode<T>(nodeData);
            treeNode.ID = this.GetUniqueID(flatDataItem);
            treeNode.Level = level;
            if (this.GetSortValue(flatDataItem) is int ordinal)
                treeNode.Ordinal = ordinal;
            return treeNode;
        }
    }
}
